#ifndef SDKMANAGER_H
#define SDKMANAGER_H

#include <QObject>
#include <QList>
#include <QDir>
#include <QPluginLoader>
#include <QSize>
#include <QVariant>
#include "SDKInterface.h"
#include "CameraSDKInterface.h"
#include "ControlModuleSDKInterface.h"



class SDKManager : public QObject {
    Q_OBJECT
public:
    explicit SDKManager(QObject *parent = nullptr);
    ~SDKManager();

    /**
     * @brief 加载指定目录下的所有SDK插件
     * @param sdkDir SDK插件目录的绝对路径
     */
    void loadSDKs(const QString &sdkDir);

    /**
     * @brief 调用指定SDK的功能函数
     * @param sdkName 目标SDK名称
     * @param funcName 目标函数名称
     * @param args 参数列表（QVariant类型）
     * @param result 输出参数，用于存储调用结果（QVariant类型）
     * @return 是否调用成功（true表示成功，false表示失败）
     */
    bool callSDKFunction(const QString& sdkName, const QString& funcName, const QVariantList& args, QVariant& result);

    /**
     * @brief 获取已加载的相机SDK列表
     * @return 相机SDK实例列表
     */
    QList<CameraSDKInterface*> loadedCameraSDKs() const;

    /**
     * @brief 获取已加载的控制模块SDK列表
     * @return 控制模块SDK实例列表
     */
    QList<ControlModuleSDKInterface*> loadedControlModuleSDKs() const;

    /**
     * @brief 根据SDK名称获取SDK实例
     * @param sdkName SDK名称
     * @return SDK实例指针，如果未找到则返回nullptr
     */
    SDKInterface* getSDKByName(const QString& sdkName) const;

    /**
     * @brief 根据SDK名称获取相机SDK实例
     * @param sdkName SDK名称
     * @return 相机SDK实例指针，如果未找到或类型不匹配则返回nullptr
     */
    CameraSDKInterface* getCameraSDKByName(const QString& sdkName) const;

    /**
     * @brief 根据SDK名称获取控制模块SDK实例
     * @param sdkName SDK名称
     * @return 控制模块SDK实例指针，如果未找到或类型不匹配则返回nullptr
     */
    ControlModuleSDKInterface* getControlModuleSDKByName(const QString& sdkName) const;

    /**
     * @brief 根据设备ID获取SDK名称
     * @param deviceId 设备ID
     * @return SDK名称，如果未找到则返回空字符串
     */
    QString getSdkNameByDeviceId(const QVariant& deviceId) const;

    /**
     * @brief 设置设备触发模式（简化版，仅传入设备ID）
     * @param deviceId 设备ID
     * @param mode 触发模式
     * @return 操作结果，0表示成功，其他表示失败
     */
    int setDeviceTriggerMode(const QVariant& deviceId, int mode);

    /**
     * @brief 发现所有相机设备（聚合所有已加载相机SDK）
     * @return 返回设备ID列表（QVariant封装字符串/数值）
     */
    QList<QVariant> discoverCameraDevices();
    /**
     * @brief 发现所有控制模块设备（聚合所有已加载控制模块SDK）
     * @return 返回设备ID列表（QVariant封装字符串/数值）
     */
    QList<QVariant> discoverControlModuleDevices();

    /**
     * @brief 连接指定设备（根据设备ID路由到对应SDK）
     * @param deviceId 设备ID
     * @return 连接是否成功
     */
    bool connectDevice(const QVariant& deviceId);
    /**
     * @brief 断开指定设备（根据设备ID路由到对应SDK）
     * @param deviceId 设备ID
     */
    void disconnectDevice(const QVariant& deviceId);

    /**
     * @brief 获取设备像素尺寸（宽高）
     * @param deviceId 设备ID
     * @return 设备像素尺寸，失败返回空尺寸
     */
    QSize getDevicePixelSize(const QVariant& deviceId);

    /**
     * @brief 注册图像采集回调
     * @param deviceId 设备ID
     * @param callback 图像回调函数（参数为设备ID和原始字节数组指针）
     * @return 是否设置成功
     */
    bool setImageCaptureCallback(const QVariant& deviceId, ImageCallback callback);

    /**
     * @brief 取消图像采集回调
     * @param deviceId 设备ID
     */
    void unsetImageCaptureCallback(const QVariant& deviceId);

    /**
     * @brief 控制模块通用参数读取
     * @param deviceId 设备ID
     * @param paramName 参数名称
     * @return 参数值
     */
    QVariant getControlModuleParameter(const QVariant& deviceId, const QString& paramName) const;

    /**
     * @brief 获取设备参数对话框
     * @param deviceId 设备ID
     * @return 设备参数对话框指针，如果不支持则返回nullptr
     */
    QDialog* getDeviceParameterDialog(const QVariant& deviceId, QWidget *parent);

    /**
     * @brief 获取设备快捷参数设置widget
     * @param deviceId 设备ID
     * @return 快捷参数设置widget指针，如果不支持则返回nullptr
     */
    QWidget* getDeviceQuickParameterWidget(const QVariant& deviceId);
    
    /**
     * @brief 设置设备参数
     * @param deviceId 设备ID
     * @param params 设备参数映射，使用QVariantMap作为万能变量类型
     * @return 设置成功返回true，失败返回false
     */
    bool setDeviceParameters(const QVariant& deviceId, const QVariantMap& params);
    
    /**
     * @brief 获取设备参数
     * @param deviceId 设备ID
     * @param configName 配置名称输出
     * @param params 设备参数映射输出，使用QVariantMap作为万能变量类型
     * @return 获取成功返回true，失败返回false
     */
    bool getDeviceParameters(const QVariant& deviceId, QString& configName, QVariantMap& params);
    
    /**
     * @brief 设置预设参数
     * @param configName  配置名称
     * @param params 预设参数映射，使用QVariantMap作为万能变量类型
     * @return 设置成功返回true，失败返回false
     */
    bool setPresetParameters(const QString &configName, const QVariantMap& params);
    
    /**
     * @brief 获取预设参数
     * @param configName 配置名称输出
     * @param params 预设参数映射输出，使用QVariantMap作为万能变量类型
     * @return 获取成功返回true，失败返回false
     */
    bool getPresetParameters(const QString &configName, QVariantMap& params);

signals:
    /**
     * @brief 相机连接信号
     * @param deviceId 设备ID
     */
    void cameraConnected(const QString& deviceId);
    /**
     * @brief 相机断开连接信号
     * @param deviceId 设备ID
     */
    void cameraDisconnected(const QString& deviceId);
    /**
     * @brief 控制模块连接信号
     * @param deviceId 设备ID
     */
    void controlModuleConnected(const QString& deviceId);
    /**
     * @brief 控制模块断开连接信号
     * @param deviceId 设备ID
     */
    void controlModuleDisconnected(const QString& deviceId);
    /**
     * @brief 日志写入信号
     * @param logInfo 日志信息
     * @param logLevel 日志级别（默认0）
     * @param isSave 是否保存到文件（默认false）
     */
    void writeLog(const QString& logInfo,int logLevel=0,bool isSave=false);

private:
    QMap<QString, CameraSDKInterface*> m_cameraSDKs; ///< 相机SDK实例映射表，键为SDK名称
    QMap<QString, ControlModuleSDKInterface*> m_controlModuleSDKs; ///< 控制模块SDK实例映射表，键为SDK名称
    QMap<QString, QString> m_deviceIdToSdkName; ///< 设备ID到SDK名称的映射表（使用字符串键避免QVariant比较弃用问题）
};

#endif // SDKMANAGER_H
